﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PayloadTracker.APRS.Parsers
{
    [ParserName("APRS Plain Parser")]
    class APRSPlain : IParser
    {

        /*
         N0KKZ-3>APRS:@140003h3936.68N/10402.55WO063/008/A=005230
           1       2       3     4         5    6 7   8     9
         
         *  
         * 1) N0KKZ-3    = callsign
         * 2) APRS:@     = identifier
         * 3) 140003h    = UTCTime
         * 4) 3936.68N   = Latitude
         * 5) 10402.55W  = Longitude
         * 6) O          = Symbol Switch
         * 7) 063        = Course degrees
         * 8) 008        = Speed  knots.
         * 9) 005230     = Altitude ft.
         * 
         
        */

        // /051622h4733.64N/12220.32W>024/000/A=000000/microtrack


        public override APRSBeacon Parse(string sentence)
        {
            if(!IsValidSentence(sentence))
                throw new Exception("Invalid Sentence");

            APRSBeacon ret = new APRSBeacon();

            string callsign = sentence.Substring(0, sentence.IndexOf('>'));

            if (sentence.Contains("@"))
                sentence = sentence.Substring(sentence.IndexOf('@') + 1); //trim callsign and sentence identifier.
            else
                sentence = sentence.Substring(sentence.IndexOf(":/") + 2);
            
            string UTCTime = sentence.Substring(0, sentence.IndexOf('h'));
            sentence = sentence.Substring(sentence.IndexOf('h') + 1); //trim time and 'h'

            //string Latitude = sentence.Substring(0, sentence.IndexOf('/') - 1);
            //sentence = sentence.Substring(Latitude.Length + 2); //strip off latitude, bearing, and slash.

            string Latitude;
            try
            {
                Latitude = sentence.Substring(0, sentence.IndexOf('N'));
            }
            catch (System.Exception ex)
            {
                Latitude = sentence.Substring(0, sentence.IndexOf('S'));
            }

            string LatitudeBearing = sentence.Substring(Latitude.Length, 1);
            sentence = sentence.Substring(Latitude.Length + 1);

            string imageSym1 = sentence.Substring(0, 1);
            sentence = sentence.Substring(1);

            string Longitude;
            try
            {
                Longitude = sentence.Substring(0, sentence.IndexOf('W'));

            }
            catch (System.Exception)
            {
                Longitude = sentence.Substring(0, sentence.IndexOf('E'));
            }
            string LongitudeBearing = sentence.Substring(Longitude.Length, 1);
            sentence = sentence.Substring(Longitude.Length + 1); //strip off longitude, bearing, and symbol.

            char imageSym2 = sentence.Substring(0, 1)[0];

            sentence = sentence.Substring(1);

            string Course = sentence.Substring(0, sentence.IndexOf('/'));

            sentence = sentence.Substring(Course.Length + 1);
            string Speed = sentence.Substring(0, sentence.IndexOf('/'));
            sentence = sentence.Substring(Speed.Length + 3);

            string Altitude = sentence;

            if (Altitude.Contains("/"))
                Altitude = Altitude.Substring(0, Altitude.IndexOf('/'));

            ret.ImageIndex = new object[] { imageSym1, APRSSymbols.GetIndexofSym(imageSym2) };
            ret.Callsign = callsign;
            ret.Course = float.Parse(Course);
            ret.Position = new Coordinate(Tools.GPSToDecimalDegrees(Latitude, LatitudeBearing), Tools.GPSToDecimalDegrees(Longitude, LongitudeBearing));
            ret.Time = Tools.NMEAUTCTimeToUTCDateTime(UTCTime);
            //ret.Altitude = Tools.MetersToFeet(double.Parse(Altitude));
            ret.Altitude = float.Parse(Altitude);
            ret.Speed = Tools.KnotsToMPH(double.Parse(Speed));


            return ret;
        }

        public override bool IsValidSentence(string sentence)
        {
            return /*sentence.Contains(">APRS:@") && */
                (sentence.Contains('O') || sentence.Substring(1).Contains('>')) &&
                sentence.Contains("A=") &&
                sentence.Split('/').Length >= 4;
        }
    }
}
